SpringCloudAlibaba 入门笔记(三)Nacos 配置中心

概述

Nacos 还为我们提供了类似于 Spring Cloud Config 的配置管理功能,通过 Nacos ,我们可以对各个服务的配置进行集中管理,并且可以在服务运行时动态调整配置。

本篇我们将以 Nacos 作为配置中心,实现服务的外置化配置、动态配置更新以及基于profile的环境切换。

外部化配置

配置依赖

首先,我们来创建一个 SpringBoot 项目,实现一个简单的CRUD功能,这里就不贴代码出来了,可以参考 sample-2

然后,引入如下依赖,启用 Nacos 的配置中心功能:

1
2
3
4
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>

修改数据源

接下来,我们来对项目进行一些修改。

通常,我们会在 SpringBoot 的 application.yml 中配置数据源,比如:

1
2
3
4
5
6
7
8
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
druid:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/ms?useUnicode=true&characterEncoding=utf8
username: root
password:

现在,我们尝试去把关于数据源的配置放在项目外部,也就是放在Nacos配置中心。但是我们知道,IOC容器在进行初始化时会去读取配置文件中的内容,因此,我们需要在IOC容器初始化之前,到Nacos配置中心获取配置,这里就需要用到bootstrap.yml,bootstrap.yml会在IOC容器启动前加载,以此可以实现配置数据的远端加载。

bootstrap.yml内容如下:

1
2
3
4
5
6
7
8
spring:
application:
name: nacos-config
cloud:
nacos:
config:
server-addr: 127.0.0.1:8848
file-extension: yaml

可以看到,我们在bootstrap.yml中配置了nacos的地址,并通过file-extension注明了配置文件的格式,这样在启动应用后,就会自动到nacos中读取nacos-config.yml的配置。

接下来,我们继续修改项目,将原本在application.yml中配置的数据源修改为配置类的方式。

这里使用了阿里的Druid数据库连接池,我们先来创建一个Bean,用于保存Druid的配置信息,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
@Component
@Primary
public class DruidProperty {
@Value("${spring.datasource.driver-class-name}")
private String driverClassName;
@Value("${spring.datasource.url}")
private String url;
@Value("${spring.datasource.username}")
private String username;
@Value("${spring.datasource.password}")
private String password;

public String getDriverClassName() {
return driverClassName;
}

public String getUrl() {
return url;
}

public String getUsername() {
return username;
}

public String getPassword() {
return password;
}
}

然后,创建数据源DruidDataSource,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Configuration
public class DruidConfig {
@Autowired
private DruidProperty druidProperty;

@Bean
@Primary
public DataSource druidDataSource() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(druidProperty.getDriverClassName());
dataSource.setUrl(druidProperty.getUrl());
dataSource.setUsername(druidProperty.getUsername());
dataSource.setPassword(druidProperty.getPassword());
return dataSource;
}
}

到这里,项目的修改工作就完成了,接下来还需要到nacos中创建配置

创建配置

启动nacos,访问localhost:8848,账号密码均为nacos,登录到nacos的控制台。

在配置列表中,我们创建一个DataId为nacos-config.yaml的配置文件,配置格式为前面file-extension对应的yaml格式,内容与前面的DruidProperty的取值相对应,如下:

1
2
3
4
spring.datasource.driver-class-name: com.mysql.jdbc.Driver
spring.datasource.url: jdbc:mysql://localhost:3306/spring-cloud-alibaba-demo-dev?useUnicode=true&characterEncoding=utf8
spring.datasource.username: root
spring.datasource.password:

保存后,我们启动nacos-config这个项目,访问我之前写好的接口,就会发现可以从我们配置的数据源中正确读取数据了。

动态配置更新

考虑我们又有一个新的需求:在服务运行期间去修改服务的配置,这里我们以切换服务的数据源为目标。

配置Actuator

Actuator可以帮助我们监控和管理Spring Boot应用,并通过一些HTTP端点来进行健康检查、统计等操作。

在项目中添加如下依赖:

1
2
3
4
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

在application.yml中配置,暴露出HTTP端点:

1
2
3
4
5
management:
endpoints:
web:
exposure:
include: '*'

添加@RefreshScope

@RefreshScope注解是实现动态配置更新的重要注解。

当我们调用/actuator/refresh端点时,springboot会用新配置创建一个新的IOC容器,然后与原IOC容器的配置进行比较,找出那些修改了的配置,然后使用新配置重新创建由@RefreshScope注解的Bean。

修改DruidProperty类和DruidDataSource类,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
@RefreshScope
@Component
@Primary
public class DruidProperty {
@Value("${spring.datasource.driver-class-name}")
private String driverClassName;
@Value("${spring.datasource.url}")
private String url;
@Value("${spring.datasource.username}")
private String username;
@Value("${spring.datasource.password}")
private String password;

public String getDriverClassName() {
return driverClassName;
}

public String getUrl() {
return url;
}

public String getUsername() {
return username;
}

public String getPassword() {
return password;
}
}

@Configuration
public class DruidConfig {
@Autowired
private DruidProperty druidProperty;

@RefreshScope
@Bean
@Primary
public DataSource druidDataSource() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(druidProperty.getDriverClassName());
dataSource.setUrl(druidProperty.getUrl());
dataSource.setUsername(druidProperty.getUsername());
dataSource.setPassword(druidProperty.getPassword());
return dataSource;
}
}

这里有一点需要注意,@RefreshScope注解不应与@Configuration注解同时使用,官方给出的说明是同时使用会出现意想不到的情况,@RefreshScope应当标注在那些需要重新创建的Bean上。

OK,这样我们就完成了对项目的修改,启动项目后,我们通过nacos控制台对项目配置的数据源进行修改,再次访问项目时就会发现,项目已经自动切换了数据源。

基于profile的环境切换

通常,我们会通过profile来管理项目的配置,比如开发环境、测试环境、生产环境等等。

在以nacos作为配置中心时,也可以非常方便的使用这一特性,我们还需要在bootstrap.yml中添加激活的profile,如下:

1
2
3
4
5
6
7
8
9
10
spring:
application:
name: nacos-config
cloud:
nacos:
config:
server-addr: 127.0.0.1:8848
file-extension: yaml
profiles:
active: dev

这样,在启动项目后,会自动到nacos中寻找dataId为nacos-config-dev.yml的配置,我们只需要以这样的命名规则,在nacos中创建配置,就可以通过profile来切换配置环境了。

源码地址:https://github.com/GreedyStar/spring-cloud-alibaba-demo

最后的最后,安利一下自己写的一个Java代码生成工具,能够方便的生成Spring、SpringMVC、Mybatis架构下的Java代码,希望能对大家有所帮助,地址:Java代码生成器:Generator